using System;
using CommonDomain.Persistence;

namespace Sponsorship.Domain.Sponsors
{
    /// <summary>
    /// Handles domain commands dealing with <see cref="Sponsor"/> instances.
    /// </summary>
    public class SponsorCommandHandler :
        ICommandHandler<EnterSponsor>,
        ICommandHandler<ChangeSponsor>,
        ICommandHandler<DeleteSponsor>
    {
        private readonly IRepository _repository;

        public SponsorCommandHandler (IRepository repository)
        {
            _repository = repository;
        }

        public void Handle (EnterSponsor command)
        {
            //execute domain logic and get back a new aggregate
            var sponsor = new Sponsor (command.SponsorId, command.FirstName, command.LastName, command.BankInformation, command.Address, command.EMail, command.TelephoneNumber, command.Comment);

            //save new raised events of aggregate into eventstore
            SaveSponsor (sponsor);
        }

        public void Handle (ChangeSponsor command)
        {
            Sponsor sponsor = LoadSponsor (command.SponsorId, command.Version);

            //execute domain logic and get back a new aggregate
            sponsor.Change (command.FirstName, command.LastName, command.BankInformation, command.Address, command.EMail, command.TelephoneNumber, command.Comment);

            //save new raised events of aggregate into eventstore
            SaveSponsor (sponsor);
        }

        public void Handle (DeleteSponsor command)
        {
            Sponsor sponsor = LoadSponsor (command.SponsorId, command.Version);

            //execute domain logic and get back a new aggregate
            sponsor.Delete();

            //save new raised events of aggregate into eventstore
            SaveSponsor (sponsor);
        }

        private Sponsor LoadSponsor (Guid guid)
        {
            return _repository.GetById<Sponsor> (guid);
        }

        private Sponsor LoadSponsor (Guid guid, int version)
        {
            return _repository.GetById<Sponsor> (guid, version);
        }

        private void SaveSponsor (Sponsor person)
        {
            _repository.Save (person, Guid.NewGuid()); // Every commit has a new ID
        }
    }
}